<template>
    <el-table v-bind="tableProps" :data="tableData" :border="tableConfig.border ?? true"
        :stripe="tableConfig.stripe ?? false" :loading="tableConfig.loading ?? false"
        @selection-change="handleSelectionChange" @sort-change="handleSortChange">
        <!-- 复选框列 -->
        <el-table-column v-if="tableConfig.showSelection" type="selection" width="55" align="center" />

        <!-- 序号列 -->
        <el-table-column v-if="tableConfig.showIndex" type="index" :label="tableConfig.indexLabel ?? '序号'"
            :width="tableConfig.indexWidth ?? 60" align="center" />

        <!-- 自定义列 -->
        <template v-for="column in tableConfig.columns" :key="column.prop">
            <el-table-column :prop="column.prop as string" :label="column.label" :width="column.width"
                :min-width="column.minWidth" :align="column.align ?? 'left'" :sortable="column.sortable ?? false"
                :fixed="column.fixed" :formatter="column.formatter">
                <template #default="scope">
                    <!-- 自定义渲染函数 -->
                    <template v-if="column.render">
                        {{ column.render(scope.row, scope.column, scope.$index) }}
                    </template>
                    <!-- 插槽 -->
                    <template v-else-if="column.slotName">
                        <slot :name="column.slotName" :row="scope.row" :index="scope.$index" />
                    </template>
                    <!-- 默认显示 -->
                    <template v-else>
                        {{ scope.row[column.prop as string] }}
                    </template>
                </template>
            </el-table-column>
        </template>

        <!-- 操作列 -->
        <el-table-column v-if="tableConfig.operationColumn" :label="tableConfig.operationColumn.label ?? '操作'"
            :width="tableConfig.operationColumn.width ?? 150" :align="tableConfig.operationColumn.align ?? 'center'"
            :fixed="tableConfig.operationColumn.fixed">
            <template #default="scope">
                <slot name="operation" :row="scope.row" :index="scope.$index" />
            </template>
        </el-table-column>
    </el-table>
</template>

<script setup lang="ts">
import { defineProps, withDefaults, defineEmits } from 'vue';
import type { TableColumnCtx } from 'element-plus';

// Element Plus的排序变更事件类型定义
interface SortingColumn {
    column: TableColumnCtx<any>;
    prop: string | undefined;
    order: 'ascending' | 'descending' | null;
}

// 定义列配置类型
interface ColumnConfig<T extends Record<string, any> = any> {
    // 字段名
    prop: keyof T | string;
    // 列标题
    label: string;
    // 列宽
    width?: number;
    // 最小列宽
    minWidth?: number;
    // 对齐方式
    align?: 'left' | 'center' | 'right';
    // 是否可排序
    sortable?: boolean | 'custom';
    // 是否固定列
    fixed?: 'left' | 'right' | boolean;
    // 自定义格式化函数
    formatter?: (row: T, column: TableColumnCtx<T>, cellValue: any, index: number) => string;
    // 自定义渲染函数
    render?: (row: T, column: TableColumnCtx<T>, index: number) => any;
    // 插槽名称
    slotName?: string;
}


// 定义操作列配置类型
interface OperationColumnConfig {
    // 列标题
    label?: string;
    // 列宽
    width?: number;
    // 对齐方式
    align?: 'left' | 'center' | 'right';
    // 是否固定列
    fixed?: 'left' | 'right' | boolean;
}

// 定义表格配置类型
export interface TableConfig<T extends Record<string, any> = any> {
    // 表格数据
    data: T[];
    // 列配置
    columns: ColumnConfig<T>[];
    // 是否显示复选框
    showSelection?: boolean;
    // 是否显示序号列
    showIndex?: boolean;
    // 序号列标题
    indexLabel?: string;
    // 序号列宽度
    indexWidth?: number;
    // 是否显示边框
    border?: boolean;
    // 是否显示斑马纹
    stripe?: boolean;
    // 是否加载中
    loading?: boolean;
    // 操作列配置
    operationColumn?: OperationColumnConfig;
}

// 定义组件属性
const props = withDefaults(
    defineProps<{
        // 表格配置
        tableConfig: TableConfig;
        // 其他el-table属性
        tableProps?: Partial<any>;
    }>(),
    {
        tableProps: () => ({})
    }
);
const tableData = computed(() => props.tableConfig.data);
// 定义组件事件
const emits = defineEmits<{
    (e: 'selection-change', val: any[]): void;
    (e: 'sort-change', val: SortingColumn): void;
}>();

// 处理选择变化
const handleSelectionChange = (selection: any[]) => {
    emits('selection-change', selection);
};

// 处理排序变化
const handleSortChange = (sort: SortingColumn) => {
    emits('sort-change', sort);
};

// 解构props
const { tableConfig, tableProps } = props;
</script>
